package com.dkd.sbtz.service.impl;

import java.util.*;
import java.util.stream.Collectors;

import com.dkd.common.exception.ServiceException;
import com.dkd.common.utils.SecurityUtils;
import com.dkd.common.utils.StringUtils;
import com.dkd.sbtz.domain.vo.sbtype.SaveTypeRelationsReq;
import com.dkd.sbtz.domain.vo.sbtype.TypeRelation;
import com.dkd.sbtz.domain.vo.sbtype.TypeRelationsVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.dkd.sbtz.mapper.SbtypeMapper;
import com.dkd.sbtz.domain.Sbtype;
import com.dkd.sbtz.service.ISbtypeService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 设备类型Service业务层处理
 * 
 * @author xzj
 * @date 2025-09-02
 */
@Service
public class SbtypeServiceImpl implements ISbtypeService 
{
    @Autowired
    private SbtypeMapper sbtypeMapper;

    /**
     * 查询设备类型
     * 
     * @param typeCode 设备类型主键
     * @return 设备类型
     */
    @Override
    public Sbtype selectSbtypeByTypeCode(String typeCode)
    {
        return sbtypeMapper.selectSbtypeByTypeCode(typeCode);
    }

    /**
     * 查询设备类型列表
     * 
     * @param sbtype 设备类型
     * @return 设备类型
     */
    @Override
    public List<Sbtype> selectSbtypeList(Sbtype sbtype) {
        // 1. 先查分页列表
        List<Sbtype> list = sbtypeMapper.selectSbtypeList(sbtype);
        if (list == null || list.isEmpty()) return list;

        // 2. 抽取本页所有 typeCode
        List<String> typeCodes = list.stream()
                .map(Sbtype::getTypeCode)
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.toList());
        if (typeCodes.isEmpty()) return list;

        // 3. 一次性批量把父/子关系查出来
        List<TypeRelation> rows = sbtypeMapper.selectTypeRelationsBatch(typeCodes);

        // 4. 按 currentCode 分组
        Map<String, List<TypeRelation>> grouped = rows.stream()
                .filter(r -> r.getCurrentCode() != null && r.getRelationType() != null)
                .collect(Collectors.groupingBy(TypeRelation::getCurrentCode));

        // 5. 组装回列表对象
        for (Sbtype t : list) {
            List<TypeRelation> relations = grouped.getOrDefault(t.getTypeCode(), Collections.emptyList());
            String parents = relations.stream()
                    .filter(r -> "parent".equals(r.getRelationType()) && r.getName() != null)
                    .map(TypeRelation::getName)
                    .distinct()
                    .collect(Collectors.joining("，"));
            String children = relations.stream()
                    .filter(r -> "child".equals(r.getRelationType()) && r.getName() != null)
                    .map(TypeRelation::getName)
                    .distinct()
                    .collect(Collectors.joining("，"));
            t.setParentNames(parents);
            t.setChildNames(children);
        }
        return list;
    }

    @Override
    public TypeRelationsVO getRelations(String typeCode) {
        // 复用批量查询，只传一个 code
        List<TypeRelation> rows = sbtypeMapper.selectTypeRelationsBatch(Collections.singletonList(typeCode));

        List<String> parents = rows.stream()
                .filter(r -> "parent".equals(r.getRelationType()) && StringUtils.isNotEmpty(r.getCode()))
                .map(TypeRelation::getCode)
                .distinct()
                .collect(Collectors.toList());

        List<String> children = rows.stream()
                .filter(r -> "child".equals(r.getRelationType()) && StringUtils.isNotEmpty(r.getCode()))
                .map(TypeRelation::getCode)
                .distinct()
                .collect(Collectors.toList());

        TypeRelationsVO vo = new TypeRelationsVO();
        vo.setTypeCode(typeCode);
        vo.setParents(parents);
        vo.setChildren(children);
        return vo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveRelations(SaveTypeRelationsReq req) {
        String typeCode = Optional.ofNullable(req.getTypeCode()).orElse("").trim();
        if (typeCode.isEmpty()) {
            throw new IllegalArgumentException("typeCode 不能为空");
        }

        // 去空、去重、去自身
        List<String> parentTypes = Optional.ofNullable(req.getParentTypes()).orElse(Collections.emptyList())
                .stream().filter(Objects::nonNull).map(String::trim)
                .filter(s -> !s.isEmpty() && !s.equals(typeCode)).distinct().collect(Collectors.toList());

        List<String> childTypes = Optional.ofNullable(req.getChildTypes()).orElse(Collections.emptyList())
                .stream().filter(Objects::nonNull).map(String::trim)
                .filter(s -> !s.isEmpty() && !s.equals(typeCode)).distinct().collect(Collectors.toList());

        String username = SecurityUtils.getUsername();

        // 1) 先清空“当前 -> 所有子”
        sbtypeMapper.deleteByParentType(typeCode);
        // 再批量插入（当前为 parent，childTypes 为子）
        if (!childTypes.isEmpty()) {
            sbtypeMapper.insertBatch(typeCode, childTypes, username);
        }

        // 2) 再清空“所有父 -> 当前”
        sbtypeMapper.deleteByChild(typeCode);
        // 再批量插入（parentTypes 为父，当前为 child）
        if (!parentTypes.isEmpty()) {
            sbtypeMapper.insertParentBatch(typeCode, parentTypes, username);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateDeviceCount(Sbtype sbtype) {
        // 只更新设备台数字段
        Sbtype updateEntity = new Sbtype();
        updateEntity.setTypeCode(sbtype.getTypeCode());
        updateEntity.setDeviceCount(sbtype.getDeviceCount());

        return sbtypeMapper.updateDeviceCount(updateEntity);
    }


    /**
     * 新增设备类型
     * 
     * @param sbtype 设备类型
     * @return 结果
     */
    @Override
    public int insertSbtype(Sbtype sbtype)
    {
        return sbtypeMapper.insertSbtype(sbtype);
    }

    /**
     * 修改设备类型
     * 
     * @param sbtype 设备类型
     * @return 结果
     */
    @Override
    public int updateSbtype(Sbtype sbtype)
    {
        return sbtypeMapper.updateSbtype(sbtype);
    }

    /**
     * 批量删除设备类型
     * 
     * @param typeCodes 需要删除的设备类型主键
     * @return 结果
     */
    @Override
    public int deleteSbtypeByTypeCodes(String[] typeCodes)
    {
        sbtypeMapper.deleteEdgesByTypeCodes(typeCodes);
        return sbtypeMapper.deleteSbtypeByTypeCodes(typeCodes);
    }

    /**
     * 删除设备类型信息
     * 
     * @param typeCode 设备类型主键
     * @return 结果
     */
    @Override
    public int deleteSbtypeByTypeCode(String typeCode)
    {
        return sbtypeMapper.deleteSbtypeByTypeCode(typeCode);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public int replaceChildren(String parentType, List<String> childTypes) {
        if (StringUtils.isEmpty(parentType)) return 0;

        // 1) 清空旧关系
//        sbtypeMapper.deleteByParentType(parentType);

        // 2) 批量插入新关系（可为空数组：表示清空后的状态）
        if (childTypes == null || childTypes.isEmpty()) return 0;

        List<String> data = new ArrayList<>(childTypes);
        String username = SecurityUtils.getUsername(); // RuoYi 提供
        return sbtypeMapper.insertBatch(parentType, data, username);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void bindParent(String childType, List<String> parentTypes) {
        // 先清空旧关系
//        sbtypeMapper.deleteByChild(childType);

        // 为空数组 => 表示清空，直接返回
        if (parentTypes == null || parentTypes.isEmpty()) return;

        // 去重、排除与自身相等
        parentTypes = parentTypes.stream()
                .filter(p -> p != null && !p.equals(childType))
                .distinct()
                .toList();

        if (!parentTypes.isEmpty()) {
            sbtypeMapper.insertParentBatch(childType, parentTypes, SecurityUtils.getUsername());
        }
    }
}
